<template>
    <div>
        折线图
        <svg width="500" height="300"></svg>
    </div>
</template>

<script setup>
import * as d3 from 'd3';
import { onMounted } from 'vue'


let initialData = [
    { date: "2023-01-01", value: 30 },
    { date: "2023-02-01", value: 50 },
    { date: "2023-03-01", value: 60 },
    { date: "2023-04-01", value: 40 },
    { date: "2023-05-01", value: 70 },
    { date: "2023-06-01", value: 90 }
];

let finalData = [
    { date: "2023-01-01", value: 50 },
    { date: "2023-02-01", value: 70 },
    { date: "2023-03-01", value: 80 },
    { date: "2023-04-01", value: 60 },
    { date: "2023-05-01", value: 90 },
    { date: "2023-06-01", value: 110 }
];
const drawChart = () => {
    const svg = d3.select("svg"),
        margin = { top: 20, right: 20, bottom: 30, left: 40 },
        width = +svg.attr("width") - margin.left - margin.right,
        height = +svg.attr("height") - margin.top - margin.bottom;

    var x = d3.scaleTime()
        .domain(d3.extent(initialData, function (d) { return new Date(d.date); }))
        .range([0, width]);

    var y = d3.scaleLinear()
        .domain([0, d3.max(finalData, function (d) { return d.value; })])
        .range([height, 0]);

    var area = d3.area()
        .x(function (d) { return x(new Date(d.date)); })
        .y0(height)
        .y1(function (d) { return y(d.value); })
        .curve(d3.curveMonotoneX);

    var gradient = svg.append("defs")
        .append("linearGradient")
        .attr("id", "area-gradient")
        .attr("x1", "0%")
        .attr("y1", "100%")
        .attr("x2", "0%")
        .attr("y2", "0%");

    gradient.append("stop")
        .attr("offset", "0%")
        .attr("stop-color", "#8dd3c7");

    gradient.append("stop")
        .attr("offset", "100%")
        .attr("stop-color", "#ffffb3");

    const updateData = (newData) => {
        path.datum(newData)
            .transition()
            .duration(1000)
            .ease(d3.easeLinear)
            .attr("d", area);
    }
    var path = svg.append("path")
        .datum(initialData)
        .attr("class", "area")
        .attr("d", area)
        .attr("fill", "url(#area-gradient)")
        .attr("stroke", "steelblue")
        .attr("stroke-width", 2);

    // X轴
    svg.append("g")
        .attr("transform", "translate(0," + height + ")")
        .call(d3.axisBottom(x));

    // Y轴
    svg.append("g")
        .call(d3.axisLeft(y));

    // 初始状态
    updateData(initialData);

    // 模拟数据变化
    setTimeout(function () {
        updateData(finalData);
    }, 2000);
}

onMounted(() => {
    drawChart() // 1000ms = 1s, 1000 * 60 * 60 = 360
    // 1s 刷新一次
})

</script>

<style scoped lang="scss"></style>